﻿#ifndef _proxy_encrypt_h_20220720
#define _proxy_encrypt_h_20220720

#include <string.h>
#include <map>
#include "SL_asynFramePub.h"
#include "SLT_tool_pub.h"
#include "AIGCJson/AIGCJson.hpp"
#include "MacType.h"
#include "ManageProxy.h"

//#include "proxyServiceCmdDef.h"

/*本文件实现加密功能的支持: 
	和上级协商zgkey，
	支持其他服务对加密模块的初始化
*/
//没有加密模块时的编译支持
#ifndef PROXYENCRYPT
	int securev2v_symDecrypt(void* pDevice, unsigned int uiCryptoType, unsigned char* ucInData,	unsigned int uiInDataLength, 
		unsigned char* ucOutData,unsigned int* puiOutDataLength);
	int securev2v_symEncrypt(void* pDevice, unsigned int uiCryptoType, unsigned char* ucInData,	unsigned int uiInDataLength, 
		unsigned char* ucOutData,unsigned int* puiOutDataLength);
#endif


/*密码模块使用流程：
1 初始化
2 入网认证
3 同步key（rootkey）
4 协商zgkey
*/

//加密模块远程初始化.由于本地没有综管，需要远程初始化加密模块
class CProxyEncryptInitSession : public SLF_SessionBase
{
	public:
	virtual void OnStart();
	virtual void OnStop(){}
	virtual void OnMsgArrive(SLF_senderPtr &_sender,uint32_t srcSid, int msgid,SLF_sendMemBasePtr &_data);
	virtual void OnTimer(uint32_t timerID, int _intervalMs, bool periodic);

	void OnProxyClientsyncKeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void _sendProxyClientsyncKey();

	SLF_senderPtr m_senderSptr;
	SLF_sendMemBasePtr m_sendmem;
	std::string m_lastsid;

	std::string proxy_ip;
	int         proxy_port = 0;
};

//基于mac层的sender
class CProxyEncryptManage;
class CProxyMacSender: public SLF_sender
{
public:
	CProxyMacSender(CProxyEncryptManage *p){m_pManage = p;}
	virtual bool SLF_postMsg(uint32_t _SessID, int msgid, uint32_t _srcID,const SLF_sendMemBasePtr &_data);

	CProxyEncryptManage  *m_pManage = nullptr;
	MacType   m_remoteMac;
	//MacType   m_dstMac;
};
typedef std::shared_ptr< CProxyMacSender> CProxyMacSenderPtr;

class CProxyEncrypt
{
public:
	enum encrypt_state
	{
		encrypt_state_init,
		encrypt_state_entrynet,
		encrypt_state_syckey,
		encrypt_state_getzgkey,
		encrypt_state_ok
	};
	enum en_work_sub_state
	{
		en_work_sub_state_init,
		en_work_sub_state_start,
		en_work_sub_state_wait,
	};
	
	CProxyEncrypt();
	int entryNetStart(SLT_memDataSptr &_out_memData);
	int entryNet(char *_pdata,int _len,SLT_memDataSptr &_out_memData);

	SLT_elapseTimer  m_resendTimer;
	encrypt_state m_work_state = encrypt_state_init;
	en_work_sub_state	m_work_sub_state = en_work_sub_state_init; //命令没有添加到重发队列，需要定时重新发送
	slt_uuid_t m_uuid;
};

//class CProxyServiceCascade;
class CProxyServiceCascadeChild :public SLF_SessionBase,public CProxyEncrypt,public SLT_memLeakCheck<CProxyServiceCascadeChild>
{
public:
	CProxyServiceCascadeChild(){}
	virtual ~CProxyServiceCascadeChild(){}
	virtual void OnStart();
	virtual void OnStop();
	virtual void OnMsgArrive(SLF_senderPtr &_sender,uint32_t srcSid, int msgid,SLF_sendMemBasePtr &_data);
	virtual void OnTimer(uint32_t timerID, int _intervalMs, bool periodic);

	void OnRecvEntrynetReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void OnRecvSynckeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void OnGetzgkeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);


	SLT_recvRepeatCheck    m_recvCheck;

	//std::string m_strMac;
	MacType     m_remotemac;
	uint32_t    m_id{0};

	SLT_elapseTimer  m_delTimer; //定时删除
};
typedef std::shared_ptr<CProxyServiceCascadeChild>   CProxyServiceCascadeChildSptr;

//密钥协商父会话
class CProxyServiceCascade :public SLF_SessionBase, public CProxyEncrypt,public SLT_resendListCB
{
public:
	CProxyServiceCascade();
	virtual void OnStart();
	virtual void OnStop(){}
	virtual void OnMsgArrive(SLF_senderPtr &_sender,uint32_t srcSid, int msgid,SLF_sendMemBasePtr &_data);
	virtual void OnTimer(uint32_t timerID, int _intervalMs, bool periodic);

	virtual void SLT_RLResend(SLT_resendList* _plist,SLT_resendItemCL*pitem);
	virtual void SLT_RLTimeOut(SLT_resendList* _plist,SLT_resendItemCL* pitem){}

	void checkState(); //每秒调用一次

	void   OnRecvEntrynetResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void   OnRecvSynckeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void   OnGetzgkeyResp(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void   OnLocalGetzgkeyReq(SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);

	void   _entryNetStart();
	void   _syncKeyStart();
	void   _getZgkeyStart();

	bool   _checkResp(uint32_t _index,slt_uuid_t &_uuid);

	uint32_t  m_id{0};     //对象id
	//MacType   m_mac;       //本级级的mac地址
	MacType   m_parentMac; //父级的mac地址
	uint32_t  m_parentSessID = 0;
	CProxyMacSenderPtr  m_serversenderSptr;  //向服务发送数据的sender

	uint32_t  m_cmdindexbase= {1};    //命令唯一序号
	SLT_resendList   m_resendlist;    //命令重传队列

	SLT_elapseTimer   m_localGetKeyNOtifyTimer;
};
typedef std::shared_ptr<CProxyServiceCascade>   CProxyServiceCascadeSptr;
//密钥协商管理
class CProxyEncryptManage
{
public:
	static CProxyEncryptManage * getInst();
	int   init(ManageProxy* proxy);
	bool  isSupportEncrypt();
	void  startGetKey();

	void  recvMacData(MacType addr, DataCache data);
	void  sendMacData(MacType addr, DataCache& data);

	void* m_deviceHandle;   //加密设备
	ManageProxy  *m_pManageProxy = nullptr;

	//子节点管理
	void    recvConnect(MacType &_remoteMac,const SLF_senderPtr& _sender, uint32_t srcSid, int msgid, SLF_sendMemBasePtr& _data);
	void    delchild(CProxyServiceCascadeChild *pchild);

	CProxyServiceCascadeSptr   m_parentSession;

	std::mutex         m_childLock;
	std::map<MacType ,CProxyServiceCascadeChildSptr>  m_childs;   //key: uuid
	uint32_t   m_childIdBase{1};
};


#endif